package com.lzw.breezeNovel.webApp.service.impl.comic;

import com.lzw.breezeNovel.model.entity.pojo.comic.Comic;
import com.lzw.breezeNovel.model.entity.pojo.comic.ComicCategory;
import com.lzw.breezeNovel.model.entity.query.PaginationResultQuery;
import com.lzw.breezeNovel.model.entity.query.comic.CategoryQuery;
import com.lzw.breezeNovel.model.enums.comic.ComicStatus;
import com.lzw.breezeNovel.webApp.mapper.comic.ComicCategoryMapper;
import com.lzw.breezeNovel.webApp.mapper.comic.ComicMapper;
import com.lzw.breezeNovel.webApp.service.comic.ComicCategoryService;
import com.lzw.breezeNovel.webApp.vo.comic.ComicCategoryVo;
import com.lzw.breezeNovel.webApp.vo.comic.ComicVo;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author 清风明月
 * @Package com.lzw.breezeNovel.webApp.service.impl.comic
 * @date 2025/3/16
 * @description 漫画分类
 */
@Slf4j
@Service
@SuppressWarnings("all")
public class ComicCategoryServiceImpl implements ComicCategoryService {

    /**
     * 注入mapper
     */
    @Autowired
    private ComicCategoryMapper comicCategoryMapper;

    /**
     * 注入mapper
     */
    @Autowired
    private ComicMapper comicMapper;

    /**
     * 获取所有的漫画分类
     * @return
     */
    @Override
    @Transactional(readOnly = true)
    public List<ComicCategoryVo> getAll() {
        //获取漫画的所有的分类
        List<ComicCategory> comics = comicCategoryMapper.selectAll();
        //循环遍历
        List<ComicCategoryVo> categoryVos = comics.stream().map(comic -> {
            ComicCategoryVo comicCategoryVo = new ComicCategoryVo();
            comicCategoryVo.setId(comic.getId());
            comicCategoryVo.setCategoryName(comic.getCategoryName());
            return comicCategoryVo;
        }).collect(Collectors.toList());
        return categoryVos;
    }

    /**
     * @param type
     * @param typeName
     * @return
     */
    @Override
    public PaginationResultQuery<ComicVo> getByType(@NotNull CategoryQuery categoryQuery) {
        // 计算分页起始位置
        int start = getStart(categoryQuery.getPageNo(), categoryQuery.getPageSize());

        // 根据类别统计总数
        int count = comicMapper.selectCountByType(categoryQuery.getType());

        // 如果没有数据，直接返回空结果
        if (count == 0) {
            return new PaginationResultQuery<>(0, categoryQuery.getPageSize(), start, 0, Collections.emptyList());
        }

        // 根据不同类型获取漫画列表
        List<ComicVo> comicCategorys = fetchComicsByType(categoryQuery, start);

        // 封装结果
        return new PaginationResultQuery<>(count, categoryQuery.getPageSize(), start, comicCategorys);
    }

    /**
     * 获取推荐
     * @param categoryQuery
     * @param start
     * @return
     */
    private List<ComicVo> fetchComicsByType(@NotNull CategoryQuery categoryQuery, int start) {
        // 使用映射替代
        Map<String, Function<CategoryQuery, List<ComicVo>>> fetchers = new HashMap<>();
        fetchers.put("推荐", query -> getRecommend(query.getType(), start, query.getPageSize()));
        fetchers.put("最新", query -> getNewComic(query.getType(), start, query.getPageSize()));
        fetchers.put("热门", query -> getHotComic(query.getType(), start, query.getPageSize()));

        // 获取对应的处理方法
        Function<CategoryQuery, List<ComicVo>> fetcher = fetchers.getOrDefault(
                categoryQuery.getTypeName(),
                query -> Collections.emptyList() // 默认返回空列表
        );

        return fetcher.apply(categoryQuery);
    }


    /**
     * 获取热门的
     * @param type
     * @param start
     * @param pageSize
     * @return
     */
    @Nullable
    @Contract(pure = true)
    @Transactional(readOnly = true)
    private List<ComicVo> getHotComic(String type, int start, Integer pageSize) {
        List<Comic> comics = comicCategoryMapper.selectByTypeAndHot(type, start, pageSize);
        if(comics.isEmpty())
        {
            return null;
        }
        //拷贝数据
        List<ComicVo> comicVos = Copy(comics);
        return comicVos;
    }

    /**
     *
     * @param type
     * @param start
     * @param pageSize
     * @return
     */
    @Nullable
    @Contract(pure = true)
    @Transactional(readOnly = true)
    private List<ComicVo> getNewComic(String type, int start, Integer pageSize) {
        List<Comic> comics = comicCategoryMapper.selectByTypeAndNew(type, start, pageSize);
        if(comics.isEmpty())
        {
            return null;
        }
        //拷贝数据
        List<ComicVo> comicVos = Copy(comics);
        return comicVos;
    }

    /**
     * 推荐
     */
    @Nullable
    @Contract(pure = true)
    @Transactional(readOnly = true)
    public List<ComicVo> getRecommend(String type, int start, Integer size) {
        //更具类型获取
       List<Comic> comics =  comicCategoryMapper.selectByTypeAndRecomend(type,start,size);
       if(comics.isEmpty())
       {
           return null;
       }
        //拷贝数据
        List<ComicVo> comicVos = Copy(comics);
       return comicVos;
    }

    /**
     * 计算分页数据
     */
    @NotNull
    private Integer getStart(Integer pageNo, Integer size) {
        // 对分页参数进行校验，使用Optional简化代码
        pageNo = Optional.ofNullable(pageNo).orElse(1);
        size = Optional.ofNullable(size).orElse(10);
        pageNo = Math.max(pageNo, 1);
        size = Math.max(size, 1);
        return (pageNo - 1) * size;
    }

    /**
     * 对于漫画对象进行拷贝
     */
    @Nullable
    @Contract(pure = true)
    private List<ComicVo> Copy(@NotNull List<Comic> comicList){
        return comicList.stream().map(comic -> {
            //创建ComicVo对象
            ComicVo comicVo = new ComicVo();
            //拷贝属性
            BeanUtils.copyProperties(comic,comicVo);
            //获取漫画的状态
            Integer status = comic.getStatus();
            //根据状态获取描述
            String statusDesc = ComicStatus.getDesc(status);
            //设置状态描述
            comicVo.setStatus(statusDesc);
            //判断是否要收费
            String like = comic.getFree() == 0 ? "免费" : "付费";
            comicVo.setFree(like);
            return comicVo;
        }).collect(Collectors.toList());
    }
}
